home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 2012-05-20 | 43.1 KB | 1,200 lines
#! /bin/sh # # Script to start or stop laptop_mode, and to control various settings of the # kernel, hardware etc. that influence power consumption. # # This script is a part of Laptop Mode Tools. If you are running a supported # power management daemon, this script will be automatically called on power # state change. # # Configure laptop mode tools in /etc/laptop-mode/laptop-mode.conf, and in # the broken-out config files in /etc/laptop-mode/conf.d. # # Please consult the manual pages laptop-mode.conf(8) and laptop_mode(8) for # additional information. # # Maintainer: Ritesh Raj Sarraf (rrs@researchut.com) # Original Author: Bart Samwel (bart@samwel.tk) # Project home page: http://samwel.tk/laptop_mode # # Contributors to this script: Bart Samwel # Kiko Piris # Micha Feigin # Andrew Morton # Herve Eychenne # Dax Kelson # Jan Polacek # ... and many others that I've stopped # keeping track of. # # Based on a script for Linux 2.4 written by Jens Axboe. # ############################################################################# set -a # The laptop mode tools version number. Extracted by the installer makefile # as well, so don't change the format! LMTVERSION=1.61 # This script is loaded from multiple scripts to set the config defaults # and to read the configuration on top of those. Only when the command is # recognized does this script do anything else. VERBOSE_OUTPUT=0 ENABLE_LAPTOP_MODE_ON_BATTERY=1 ENABLE_LAPTOP_MODE_ON_AC=0 ENABLE_LAPTOP_MODE_WHEN_LID_CLOSED=0 PARTITIONS="auto /dev/mapper/*" LM_BATT_MAX_LOST_WORK_SECONDS=600 LM_AC_MAX_LOST_WORK_SECONDS=360 DEF_MAX_AGE=30 LM_READAHEAD=3072 NOLM_READAHEAD=128 CONTROL_READAHEAD=1 CONTROL_NOATIME=0 USE_RELATIME=1 CONTROL_HD_IDLE_TIMEOUT=1 LM_AC_HD_IDLE_TIMEOUT=4 # 20 seconds LM_BATT_HD_IDLE_TIMEOUT=4 # 20 seconds NOLM_HD_IDLE_TIMEOUT=244 # 2 hours DEF_UPDATE=5 DEF_XFS_AGE_BUFFER=15 DEF_XFS_SYNC_INTERVAL=30 DEF_XFS_BUFD_INTERVAL=1 XFS_HZ=100 CONTROL_MOUNT_OPTIONS=1 BATT_HD_POWERMGMT=1 LM_AC_HD_POWERMGMT=254 NOLM_AC_HD_POWERMGMT=254 CONTROL_HD_POWERMGMT=0 CONTROL_HD_WRITECACHE=0 NOLM_AC_HD_WRITECACHE=1 NOLM_BATT_HD_WRITECACHE=0 LM_HD_WRITECACHE=0 LM_DIRTY_RATIO=60 LM_DIRTY_BACKGROUND_RATIO=1 NOLM_DIRTY_BACKGROUND_RATIO=10 NOLM_DIRTY_RATIO=40 LM_SECONDS_BEFORE_SYNC=2 BATT_CPU_MAXFREQ=medium BATT_CPU_MINFREQ=slowest BATT_CPU_GOVERNOR=ondemand BATT_CPU_IGNORE_NICE_LOAD=1 LM_AC_CPU_MAXFREQ=fastest LM_AC_CPU_MINFREQ=slowest LM_AC_CPU_GOVERNOR=ondemand LM_AC_CPU_IGNORE_NICE_LOAD=1 NOLM_AC_CPU_MAXFREQ=fastest NOLM_AC_CPU_MINFREQ=slowest NOLM_AC_CPU_GOVERNOR=ondemand NOLM_AC_CPU_IGNORE_NICE_LOAD=0 CONTROL_CPU_FREQUENCY=0 HD="/dev/[hs]d[abcdefgh]" CONTROL_SYSLOG_CONF=0 LM_AC_SYSLOG_CONF=/etc/syslog-on-ac-with-lm.conf NOLM_AC_SYSLOG_CONF=/etc/syslog-on-ac-without-lm.conf BATT_SYSLOG_CONF=/etc/syslog-on-battery.conf SYSLOG_CONF_SIGNAL_PROGRAM=syslogd SYSLOG_CONF=/etc/syslog.conf CONTROL_DPMS_STANDBY=0 BATT_DPMS_STANDBY=300 LM_AC_DPMS_STANDBY=1200 NOLM_AC_DPMS_STANDBY=1200 CONTROL_CPU_THROTTLING=0 BATT_CPU_THROTTLING=medium LM_AC_CPU_THROTTLING=minimum NOLM_AC_CPU_THROTTLING=minimum CONTROL_START_STOP=1 CONTROL_TERMINAL=0 TERMINALS="/dev/vc/1 /dev/vcs1" BATT_TERMINAL_BLANK_MINUTES=1 BATT_TERMINAL_POWERDOWN_MINUTES=2 LM_AC_TERMINAL_BLANK_MINUTES=10 LM_AC_TERMINAL_POWERDOWN_MINUTES=10 NOLM_AC_TERMINAL_BLANK_MINUTES=10 NOLM_AC_TERMINAL_POWERDOWN_MINUTES=50 ENABLE_AUTO_HIBERNATION=0 HIBERNATE_COMMAND=/usr/sbin/hibernate AUTO_HIBERNATION_ON_CRITICAL_BATTERY_LEVEL=1 DISABLE_LAPTOP_MODE_ON_CRITICAL_BATTERY_LEVEL=1 AUTO_HIBERNATION_BATTERY_CHARGE_MAH=0 AUTO_HIBERNATION_BATTERY_CHARGE_MWH=0 MINIMUM_BATTERY_CHARGE_MAH=0 MINIMUM_BATTERY_CHARGE_MWH=0 ASSUME_SCSI_IS_SATA=1 CONTROL_BRIGHTNESS=0 BATT_BRIGHTNESS_COMMAND=false LM_AC_BRIGHTNESS_COMMAND=false NOLM_AC_BRIGHTNESS_COMMAND=false LOG_TO_SYSLOG=1 DEBUG=0 ENABLE_LAPTOP_MODE_TOOLS=1 # Initialize the PATH Variable export PATH="${PATH}":/bin:/sbin:/usr/bin:/usr/sbin # This is a 2 phase locking approach. LMT_REQ_LOCK is the outer lock and LMT_INVOC_LOCK is the inner lock # We take this approach to ensure the scenario that, "At any point when an event occurs (AC/BATT), the # kernel can generate multiple events spanning over a couple of events. The first event is honored and # lmt executes. If the last event triggered at the 9th second, there is a fair chance that a good amount # of state change would have occured in the OS, to honor that state, we keep an outer lock (LMT_REQ_LOCK) # handy, so that those changes can also be applied and not forgotten. # Workflow: # Event-1 is generated and lmt executes (lmt runtime could span 5-10 seconds) # At seventh second, 4 events generate. But Event-1 is still running. # We don't want to discard all the remaining 4 events, but at least honor 1 so that we can act to the changes # that occured in the last 7 seconds. # So, Event-2 acquire LMT_REQ_LOCK and waits to acquire LMT_INVOC_LOCK (which is acquire by Event-1) LMT_REQ_LOCK="/var/lock/lmt-req.lock" LMT_INVOC_LOCK="/var/lock/lmt-invoc.lock" LMT_BATTPOLL_LOCK="/var/lock/lmt-battpoll.lock" FLOCK=`which flock` checkint () { # $1 arg should be the string/integer # that you want to check for as an integer. echo $1 | grep "[^0-9]" > /dev/null 2>&1 return $?; # Returns 1 if it is an integer } # Function to handle logging LOGGER=`which logger`; log () { # $1 should be msg type # $2 should be the real msg if [ x$LOG_TO_SYSLOG = x1 ]; then # NOTE: Add the check on $2 being empty, once you are confident # that there aren't any bugs in logging. And no bugs in executing # modules and logging if [ -x $LOGGER -a "$1" != "STATUS" ]; then #if [ -z $2 ]; then # continue #elif [ "$1" = "MSG" ]; then if [ "$1" = "MSG" ]; then logger -p daemon.info -t laptop-mode "$2"; elif [ "$1" = "ERR" ]; then logger -p daemon.err -t laptop-mode "$2"; elif [ "$1" = "VERBOSE" ]; then if [ x$VERBOSE_OUTPUT = x1 ]; then logger -p daemon.debug -t laptop-mode "$2"; fi else logger -p daemon.notice -t laptop-mode "$2"; fi fi fi if [ "$1" = "VERBOSE" ]; then $LM_VERBOSE && echo "$2" >/dev/fd/2; elif [ "$1" = "ERR" ]; then echo "$2" >/dev/fd/2; else # Message of type MSG and STATUS can go to stdout. echo "$2" >/dev/fd/1; fi } enableDebug () { # Check if debug is enabled if [ x$(($(basename $1 | cut -d . -f1 | tr "[:lower:]" "[:upper:]" | sed 's/-/_/g')_DEBUG)) = x1 ]; then set -vx fi } disableDebug () { # Check if debug is enabled if [ x$(($(basename $1 | cut -d . -f1 | tr "[:lower:]" "[:upper:]" | sed 's/-/_/g')_DEBUG)) = x1 ]; then set +vx fi } # No default on these ones -- we need to detect if they have been set, for # backward compatibility with MINIMUM_BATTERY_MINUTES etc. AUTO_HIBERNATION_BATTERY_CHARGE_PERCENT= MINIMUM_BATTERY_CHARGE_PERCENT= # Backward compatibility variable that is sometimes # set externally (Debian init system) unset VERBOSE lmt_load_config () { # Source config. Some config settings have been moved from the main config file # to modular configuration files, and to support existing laptop-mode.conf # files from earlier versions, we source the modular configuration files FIRST. if [ -d /etc/laptop-mode/conf.d ] ; then for CONF in /etc/laptop-mode/conf.d/*.conf /etc/laptop-mode/conf.d/board-specific/*.conf; do if [ -r "$CONF" ] ; then . "$CONF" #Handle individual module debug settings if [ "$DEBUG" -eq 1 ]; then export $(basename $CONF | cut -d . -f1 | tr "[:lower:]" "[:upper:]" | sed 's/-/_/g')_DEBUG=1 log "VERBOSE" "Enabling debug mode for module $CONF" fi DEBUG=0 else log "MSG" "Warning: Configuration file $CONF is not readable, skipping." fi done fi if [ -r /etc/laptop-mode/laptop-mode.conf ] ; then . /etc/laptop-mode/laptop-mode.conf else log "ERR" "$0: Configuration file /etc/laptop-mode/laptop-mode.conf not present or not readable." exit 1 fi if [ x$ENABLE_LAPTOP_MODE_TOOLS = x0 ]; then log "MSG" "laptop-mode-tools is disabled in config file. Exiting" exit 0; fi # Add a simple bash debug mode switch if [ "$DEBUG" -eq 1 ]; then set -vx; fi # Support for old config settings if [ "$AC_HD" != "" ] ; then AC_HD_WITHOUT_LM="$AC_HD" AC_HD_WITH_LM="$AC_HD" fi if [ "$VERBOSE" != "" ] ; then VERBOSE_OUTPUT="$VERBOSE" fi if [ "$CPU_MAXFREQ" != "" ] ; then BATT_CPU_MAXFREQ="$CPU_MAXFREQ" fi if [ "$MAX_AGE" != "" ] ; then LM_BATT_MAX_LOST_WORK_SECONDS="$MAX_AGE" LM_AC_MAX_LOST_WORK_SECONDS="$MAX_AGE" fi if [ "$DEF_AGE" != "" ] ; then DEF_MAX_AGE="$DEF_AGE" fi if [ "$LAPTOP_MODE_ALWAYS_ON" != "" ] ; then ENABLE_LAPTOP_MODE_ALWAYS="$LAPTOP_MODE_ALWAYS_ON" fi if [ "$LM_WHEN_LID_CLOSED" != "" ] ; then ENABLE_LAPTOP_MODE_WHEN_LID_CLOSED="$LM_WHEN_LID_CLOSED" fi if [ "$REMOUNT_PARTITIONS" != "" ] ; then PARTITIONS="$REMOUNT_PARTITIONS" fi if [ "$READAHEAD" != "" ] ; then LM_READAHEAD="$READAHEAD" fi if [ "$DO_REMOUNT_NOATIME" != "" ] ; then CONTROL_NOATIME="$DO_REMOUNT_NOATIME" fi if [ "$DO_HD" != "" ] ; then CONTROL_HD_IDLE_TIMEOUT="$DO_HD" fi if [ "$AC_HD_WITH_LM" != "" ] ; then LM_AC_HD_IDLE_TIMEOUT="$AC_HD_WITH_LM" fi if [ "$AC_HD_WITHOUT_LM" != "" ] ; then NOLM_HD_IDLE_TIMEOUT="$AC_HD_WITHOUT_LM" fi if [ "$BATT_HD" != "" ] ; then LM_BATT_HD_IDLE_TIMEOUT="$BATT_HD" fi if [ "$DO_REMOUNTS" != "" ] ; then CONTROL_MOUNT_OPTIONS="$DO_REMOUNTS" fi if [ "$DO_HD_POWERMGMT" != "" ] ; then CONTROL_HD_POWERMGMT="$DO_HD_POWERMGMT" fi if [ "$AC_HDPARM_POWERMGMT_WITH_LM" != "" ] ; then LM_AC_HD_POWERMGMT="$AC_HDPARM_POWERMGMT_WITH_LM" fi if [ "$AC_HDPARM_POWERMGMT_WITHOUT_LM" != "" ] ; then NOLM_AC_HD_POWERMGMT="$AC_HDPARM_POWERMGMT_WITHOUT_LM" fi if [ "$BATT_HDPARM_POWERMGMT" != "" ] ; then BATT_HD_POWERMGMT="$BATT_HDPARM_POWERMGMT" fi if [ "$DO_WRITECACHE" != "" ] ; then CONTROL_HD_WRITECACHE="$DO_WRITECACHE" fi if [ "$AC_WRITECACHE_WITHOUT_LM" != "" ] ; then NOLM_AC_HD_WRITECACHE="$AC_WRITECACHE_WITHOUT_LM" fi if [ "$BATT_WRITECACHE" != "" ] ; then LM_HD_WRITECACHE="$BATT_WRITECACHE" fi if [ "$DIRTY_RATIO" != "" ]; then LM_DIRTY_RATIO="$DIRTY_RATIO" fi if [ "$DIRTY_BACKGROUND_RATIO" != "" ] ; then LM_DIRTY_BACKGROUND_RATIO="$DIRTY_BACKGROUND_RATIO" fi if [ "$DEF_DIRTY_RATIO" != "" ]; then NOLM_DIRTY_RATIO="$DEF_DIRTY_RATIO" fi if [ "$DEF_DIRTY_BACKGROUND_RATIO" != "" ] ; then NOLM_DIRTY_BACKGROUND_RATIO="$DEF_DIRTY_BACKGROUND_RATIO" fi if [ "$DO_CPU" != "" ] ; then CONTROL_CPU_FREQUENCY="$DO_CPU" fi if [ "$CONTROL_CPU_MAXFREQ" != "" ] ; then CONTROL_CPU_FREQUENCY="$CONTROL_CPU_MAXFREQ" fi if [ "$AC_CPU_MAXFREQ_WITH_LM" != "" ] ; then LM_AC_CPU_MAXFREQ="$AC_CPU_MAXFREQ_WITH_LM" fi if [ "$AC_CPU_MAXFREQ_WITHOUT_LM" != "" ] ; then NOLM_AC_CPU_MAXFREQ="$AC_CPU_MAXFREQ_WITHOUT_LM" fi if [ "$DO_SYSLOG" != "" ] ; then CONTROL_SYSLOG_CONF="$DO_SYSLOG" fi if [ "$SYSLOG_SIGNAL_PROGRAM" != "" ] ;then SYSLOG_CONF_SIGNAL_PROGRAM="$SYSLOG_SIGNAL_PROGRAM" fi if [ "$AC_SYSLOG_WITH_LM" != "" ] ; then LM_AC_SYSLOG_CONF="$AC_SYSLOG_WITH_LM" fi if [ "$AC_SYSLOG_WITHOUT_LM" != "" ] ; then NOLM_AC_SYSLOG_CONF="$AC_SYSLOG_WITHOUT_LM" fi if [ "$BATT_SYSLOG" != "" ] ; then BATT_SYSLOG_CONF="$BATT_SYSLOG" fi if [ "$ENABLE_LAPTOP_MODE_ALWAYS" != "" ] ; then ENABLE_LAPTOP_MODE_ON_AC="$ENABLE_LAPTOP_MODE_ALWAYS" fi if [ "$MINIMUM_BATTERY_MINUTES" != "" -a "$MINIMUM_BATTERY_CHARGE_PERCENT" = "" ] ; then # Use a very conservative estimate (1% = 1 battery minute, 100 minutes in a battery) # for backward compatibility. MINIMUM_BATTERY_CHARGE_PERCENT="$MINIMUM_BATTERY_MINUTES" fi if [ -z "$MINIMUM_BATTERY_CHARGE_PERCENT" ] ; then # Apply the default, now that we've determined that this is the minimum. MINIMUM_BATTERY_CHARGE_PERCENT=3 fi if [ "$AUTO_HIBERNATION_BATTERY_MINUTES" != "" -a "$AUTO_HIBERNATION_BATTERY_CHARGE_PERCENT" = "" ] ; then # Use a very conservative estimate (1% = 1 battery minute, 100 minutes in a battery) # for backward compatibility. AUTO_HIBERNATION_BATTERY_CHARGE_PERCENT="$AUTO_HIBERNATION_BATTERY_MINUTES" fi if [ -z "$AUTO_HIBERNATION_BATTERY_CHARGE_PERCENT" ] ; then # Apply the default, now that we've determined that this is the minimum. AUTO_HIBERNATION_BATTERY_CHARGE_PERCENT=2 fi # Postprocessing if [ "$VERBOSE_OUTPUT" -ne 0 ] ; then OUTPUT="/dev/stdout" LM_VERBOSE="[ 1 = 1 ]" else OUTPUT="/dev/null" LM_VERBOSE="[ 1 = 0 ]" fi if [ "$PARTITIONS" = "" ] ; then PARTITIONS="auto /dev/mapper/*" fi # Expand shell wild cards immediately. PARTITIONS=$( echo $PARTITIONS ) TERMINALS=$( echo $TERMINALS ) # Convert seconds to hdparm -S format # Everything over 20 minutes is interpreted as 2 hours. seconds_to_hdparm_S() { if [ "$1" -eq 0 ] ; then # disable. echo 0 elif [ "$1" -gt 0 -a "$1" -lt 5 ] ; then # 5 seconds minimum echo 1 elif [ "$1" -le $((240*5)) ] ; then # Values between 1 and 240 signify increments of 5 seconds echo $(($1 / 5)) elif [ "$1" -lt $((30*60)) ] ; then # Values between 20 and 30 minutes are rounded up to 30 minutes. echo 241 elif [ "$1" -lt $((12*30*60)) ] ; then # Values between 30 minutes and 6 hours (exclusive) yield values between # 241 and 251, in 30-minute increments. echo $(( 240 + ($1 / (30*60)) )) else # Larger values effectively indicate no timeout at all. echo 0 fi } # Convert configured idle timeouts to hdparm -S format. if [ "$LM_AC_HD_IDLE_TIMEOUT_SECONDS" != "" ] ; then LM_AC_HD_IDLE_TIMEOUT=$(seconds_to_hdparm_S $LM_AC_HD_IDLE_TIMEOUT_SECONDS) fi if [ "$LM_BATT_HD_IDLE_TIMEOUT_SECONDS" != "" ] ; then LM_BATT_HD_IDLE_TIMEOUT=$(seconds_to_hdparm_S $LM_BATT_HD_IDLE_TIMEOUT_SECONDS) fi if [ "$NOLM_HD_IDLE_TIMEOUT_SECONDS" != "" ] ; then NOLM_HD_IDLE_TIMEOUT=$(seconds_to_hdparm_S $NOLM_HD_IDLE_TIMEOUT_SECONDS) fi # Determine the power state. # First try /sys/class/power_supply/* FOUND_SYS_CLASS_POWER_SUPPLY_AC=0 export ON_AC=0 for POWER_SUPPLY in /sys/class/power_supply/* ; do if [ -f $POWER_SUPPLY/type ] ; then if [ "$(cat $POWER_SUPPLY/type)" = "Mains" ] ;then log "VERBOSE" "Determining power state from $POWER_SUPPLY/online." FOUND_SYS_CLASS_POWER_SUPPLY_AC=1 if [ "$(cat $POWER_SUPPLY/online)" = 1 ] ; then ON_AC=1 fi fi fi done if [ $FOUND_SYS_CLASS_POWER_SUPPLY_AC = 1 ] ; then # Already found it! log "VERBOSE" "Not trying other options, already found a power supply." elif [ -d /proc/acpi/ac_adapter ] ; then log "VERBOSE" "Determining power state from /proc/acpi/ac_adapter." ADAPTERS_FOUND=0 ON_AC=0 for ADAPTER in /proc/acpi/ac_adapter/* ; do if [ -f $ADAPTER/state ] ; then ADAPTERS_FOUND=1 STATUS=`awk '/^state: / { print $2 }' $ADAPTER/state` if [ "$STATUS" = "on-line" ] ; then ON_AC=1 fi fi done if [ "$ADAPTERS_FOUND" -eq 0 ] ; then ON_AC=1 fi elif [ -f /proc/pmu/info ] ; then log "VERBOSE" "Determining power state from /proc/pmu/info." if ( grep -q "^AC Power.*0$" /proc/pmu/info ) ; then log "VERBOSE" "/proc/pmu/info indicates absence of AC power." ON_AC=0 else # It is possible that there is no AC Power = 1 in the file, # but we always assume AC power when we're not sure. ON_AC=1 log "VERBOSE" "/proc/pmu/info indicates presence of AC power." fi elif [ -f /proc/apm ] ; then log "VERBOSE" "Determining power state from /proc/apm." read D1 D2 D3 APM_AC_STATE D0 </proc/apm if [ "$APM_AC_STATE" = "0x00" ] ; then ON_AC=0 else ON_AC=1 fi else log "VERBOSE" "No /sys/class/power_supply, ACPI, APM or PMU power management information found -- assuming AC power is present." ON_AC=1 fi } # The main workhorse. lmt_main_function () { if [ "$1" = "status" ] ; then # Display a status report. log "STATUS" "Mounts:" mount | sed "s/^/ /" log "STATUS" " " log "STATUS" "Drive power status:" for disk in $HD; do if [ -r $disk ]; then hdparm -C $disk 2>/dev/null | sed "s/^/ /" else log "STATUS" " Cannot read $disk, permission denied - $0 needs to be run as root" fi done log "STATUS" " " log "STATUS" "(NOTE: drive settings affected by Laptop Mode cannot be retrieved.)" log "STATUS" " " log "STATUS" "Readahead states:" cat /etc/mtab | while read DEV MP FST OPTS DUMP PASS ; do # skip funny stuff case "$FST" in rootfs|unionfs|tmpfs|squashfs|sysfs|usbfs|proc|devpts) continue ;; esac if [ -b $DEV ] ; then if [ -r $DEV ] ; then log "STATUS" " $DEV: $((`blockdev --getra $DEV` / 2)) kB" else log "STATUS" " Cannot read $DEV, permission denied - $0 needs to be run as root" fi fi done log "STATUS" " " if [ -e /var/run/laptop-mode-tools/enabled ] ; then log "STATUS" "Laptop Mode Tools is allowed to run: /var/run/laptop-mode-tools/enabled exists." else log "STATUS" "Laptop Mode Tools is NOT allowed to run: /var/run/laptop-mode-tools/enabled does not exist." fi log "STATUS" " " STATFILES="/proc/sys/vm/laptop_mode /proc/apm /proc/pmu/info /proc/sys/vm/bdflush /proc/sys/vm/dirty_ratio /proc/sys/fs/xfs/age_buffer /proc/sys/fs/xfs/sync_interval /proc/sys/fs/xfs/lm_age_buffer /proc/sys/fs/xfs/lm_sync_interval /proc/sys/vm/pagebuf/lm_flush_age /proc/sys/fs/xfs/xfsbufd_centisecs /proc/sys/fs/xfs/xfssyncd_centisecs /proc/sys/vm/dirty_background_ratio /proc/sys/vm/dirty_expire_centisecs /proc/sys/fs/xfs/age_buffer/centisecs /proc/sys/vm/dirty_writeback_centisecs /sys/devices/system/cpu/*/cpufreq/cpuinfo_*_freq /sys/devices/system/cpu/*/cpufreq/scaling_governor /proc/acpi/button/lid/*/state /proc/acpi/ac_adapter/*/state /proc/acpi/battery/*/state /sys/class/power_supply/*/online /sys/class/power_supply/*/state" for THISFILE in $STATFILES ; do if [ -e "$THISFILE" ] ; then log "STATUS" "$THISFILE:" if [ -r "$THISFILE" ] ; then cat "$THISFILE" | sed "s/^/ /" else log "STATUS" " Not accessible, permission denied - $0 needs to be run as root." fi log "STATUS" " " fi done elif [ "$1" != "readconfig" -a "$1" != "defaults" ] ; then ############################################################################# KLEVEL="$(uname -r | { IFS='.-' read a b c echo $a.$b } )" KMINOR="$(uname -r | { IFS='.-' read a b c d # Strip any stuff from the end -- only the initial digits are part of the KMINOR. echo $c | sed -e 's/\([[:digit:]]*\).*/\1/' } )" # Stop exporting everything -- what we do from here is private. set +a if [ "$1" = "--version" ] ; then log "MSG" "Laptop Mode Tools $LMTVERSION" exit 0 fi if [ ! -e /proc/sys/vm/laptop_mode ] ; then log "ERR" "Kernel does not have support for laptop mode. Please apply the laptop mode" log "ERR" "patch or install a newer kernel." exit 1 fi if [ ! -w /proc/sys/vm/laptop_mode ] ; then log "ERR" "You do not have enough privileges to enable laptop_mode." exit 1 fi INIT=0 # Display info in init script format? FORCE=0 # Force reapplying the current state? INITSCRIPT_STOP=0 # Track stop command from init script. Consumer is lm-polling daemon while [ "$1" != "" ] ; do case "$1" in init) INIT=1 ;; force) FORCE=1 ;; # Old options. We always do "auto" for any option now, but # we still have to accept the options. start) ;; stop) INITSCRIPT_STOP=1 ;; auto) ;; modules=*) MODULES=$1 MODULES=${MODULES#"modules="} ;; devices=*) DEVICES=$1 DEVICES=${DEVICES#"devices="} ;; *) log "ERR" "Unrecognized option $1." exit 1 ;; esac shift done mkdir -p /var/run/laptop-mode-tools # Used to display laptop mode state later on. This is the enabled/disabled # state for laptop mode processing, it tells us nothing about whether laptop # mode is actually _active_. STATE=enabled if [ "$ENABLE_LAPTOP_MODE_ON_BATTERY" -eq 0 -a "$ENABLE_LAPTOP_MODE_ON_AC" -eq 0 -a "$ENABLE_LAPTOP_MODE_WHEN_LID_CLOSED" -eq 0 ] ; then STATE=disabled fi # Determine whether to activate or deactivate laptop mode. ACTIVATE=0 if [ "$ON_AC" -eq 1 ] ; then if [ "$ENABLE_LAPTOP_MODE_ON_AC" -ne 0 ] ; then log "VERBOSE" "On AC power: Activating, because ENABLE_LAPTOP_MODE_ON_AC is set." ACTIVATE=1 else log "VERBOSE" "On AC power: Deactivating, because ENABLE_LAPTOP_MODE_ON_AC is not set." ACTIVATE=0 fi else if [ "$ENABLE_LAPTOP_MODE_ON_BATTERY" -ne 0 ] ; then log "VERBOSE" "On battery power: Activating, because ENABLE_LAPTOP_MODE_ON_BATTERY is set." ACTIVATE=1 else log "VERBOSE" "On battery power: Deactivating, because ENABLE_LAPTOP_MODE_ON_BATTERY is not set." ACTIVATE=0 fi fi if [ "$ENABLE_LAPTOP_MODE_WHEN_LID_CLOSED" -ne 0 -a "$ACTIVATE" -eq 0 ] ; then if [ -x "`which hal-find-by-property`" ] ; then HAL_LID_BUTTON=$(hal-find-by-property --key "button.type" --string "lid") fi if [ "$HAL_LID_BUTTON" != "" ] ; then HAL_LID_BUTTON_STATE=$(hal-get-property --udi $(hal-find-by-property --key "button.type" --string "lid") --key "button.state.value") if [ "$HAL_LID_BUTTON_STATE" = "true" ] ; then log "VERBOSE" "Setting action to \"start\" because the lid is closed (says HAL)." ACTIVATE=1 fi elif [ -f /proc/acpi/button/lid/*/state ] ; then if ( grep -q "closed" /proc/acpi/button/lid/*/state ) ; then log "VERBOSE" 'Setting action to "start" because the lid is closed (says /proc/acpi/button/lid/*/state).' ACTIVATE=1 fi else log "MSG" "Warning: ENABLE_LAPTOP_MODE_WHEN_LID_CLOSED is set, but there is no file" log "MSG" "/proc/acpi/button/lid/.../state, and hal information is not available either!" fi fi # If the init script has not been run or has been run with the "stop" # argument, then we should never start laptop mode. if [ ! -f /var/run/laptop-mode-tools/enabled ] ; then log "VERBOSE" "Laptop mode disabled because /var/run/laptop-mode-tools/enabled is missing." STATE=disabled fi if [ "$ACTIVATE" -eq 1 -a -f /etc/default/laptop-mode ] ; then . /etc/default/laptop-mode if ! ( echo "$ENABLE_LAPTOP_MODE" |grep y ) ; then log "VERBOSE" "Not starting laptop mode because it is disabled in /etc/default/laptop-mode." STATE=disabled fi fi if [ "$STATE" = "disabled" ] ; then ACTIVATE=0 fi # Check whether we are allowed to activate the data-loss-sensitive stuff. # If the battery charge is too low, we want to disable this, but not the # other power-saving stuff. if [ "$ACTIVATE" -eq 0 ] ; then ACTIVATE_WITH_POSSIBLE_DATA_LOSS=0 elif [ "$ON_AC" = 1 ] ; then log "VERBOSE" "On AC, not checking minimum battery charge." ACTIVATE_WITH_POSSIBLE_DATA_LOSS=1 else ACTIVATE_WITH_POSSIBLE_DATA_LOSS=1 ENOUGH_CHARGE=0 ENOUGH_CHARGE_TO_PREVENT_HIBERNATION=0 # Weird way of checking that /sys/class/power_supply is not empty -- but it works. if [ "$(echo /sys/class/power_supply/*)" != '/sys/class/power_supply/*' ] ; then log "VERBOSE" "Not on AC and we have battery information in /sys/class/power_supply/BAT* -- checking minimum battery charge." for BATT in /sys/class/power_supply/* ; do BATT_TYPE=$(cat $BATT/type) log "VERBOSE" "$BATT is of type $BATT_TYPE." if [ "$BATT_TYPE" != "Battery" ] ; then log "VERBOSE" "Not of type \"Battery\", skipping." else PREV_ENOUGH_CHARGE=$ENOUGH_CHARGE PREV_ENOUGH_CHARGE_TO_PREVENT_HIBERNATION=$ENOUGH_CHARGE_TO_PREVENT_HIBERNATION log "VERBOSE" "Checking levels for $BATT." PRESENT=$(cat $BATT/present) log "VERBOSE" "Present: $PRESENT." # Only do if the battery is present if [ "$PRESENT" -eq 1 ] ; then FOUND_AN_ENABLED_CHECK=0 FOUND_AN_ENABLED_HIBERNATION_CHECK=0 # Get the remaining capacity. IN_UAH=0 IN_UWH=0 if [ -f $BATT/charge_now ] ; then REMAINING=$(cat $BATT/charge_now) IN_UAH=1 # charge_* is in microAmpere-hours elif [ -f $BATT/energy_now ] ; then REMAINING=$(cat $BATT/energy_now) IN_UWH=1 # energy_* is in microWatt-hours else REMAINING=0 fi if [ -z "$REMAINING" -o "$REMAINING" -eq 0 ] ; then log "VERBOSE" "Battery does not report remaining charge. Perhaps it is not present?" REMAINING=0 fi log "VERBOSE" "Remaining charge: $REMAINING" if [ -f $BATT/charge_full_design ] ; then CAPACITY=$(cat $BATT/charge_full_design) elif [ -f $BATT/energy_full_design ] ; then CAPACITY=$(cat $BATT/energy_full_design) else CAPACITY=0 fi if [ -z "$CAPACITY" -o "$CAPACITY" -eq 0 ] ; then log "VERBOSE" "Battery does not report design full charge, using non-design full charge." if [ -f $BATT/charge_full ] ; then CAPACITY=$(cat $BATT/charge_full) elif [ -f $BATT/energy_full_design ] ; then CAPACITY=$(cat $BATT/energy_full) else CAPACITY=0 fi if [ -z "$CAPACITY" -o "$CAPACITY" -eq 0 ] ; then log "VERBOSE" "Battery does not report non-design full charge." CAPACITY=0 fi fi log "VERBOSE" "Full capacity: $CAPACITY" # Check the charge percentage if [ "$MINIMUM_BATTERY_CHARGE_PERCENT" -ne 0 ] ; then FOUND_AN_ENABLED_CHECK=1 if [ "$CAPACITY" -eq 0 ] ; then log "MSG" "WARNING: Battery does not report a capacity. Minimum battery" log "MSG" "charge checking does not work without a design capacity." ENOUGH_CHARGE=1 elif [ "$(($REMAINING * 100 / $CAPACITY))" -ge "$MINIMUM_BATTERY_CHARGE_PERCENT" ] ; then ENOUGH_CHARGE=1 fi fi if [ "$AUTO_HIBERNATION_BATTERY_CHARGE_PERCENT" -ne 0 ] ; then FOUND_AN_ENABLED_HIBERNATION_CHECK=1 if [ "$CAPACITY" -eq 0 ] ; then log "MSG" "WARNING: Battery does not report a design capacity. Auto hibernation" log "MSG" "does not work without a design capacity." ENOUGH_CHARGE=1 elif [ "$(($REMAINING * 100 / $CAPACITY))" -ge "$AUTO_HIBERNATION_BATTERY_CHARGE_PERCENT" ] ; then ENOUGH_CHARGE_TO_PREVENT_HIBERNATION=1 fi fi if [ -f $BATT/alarm ]; then # $BATT/alarm is the design_capacity_warning of a battery. ALARM_LEVEL=$(cat $BATT/alarm) elif [ -f $BATT/energy_full ]; then # On Arm, it has been reported that there's no design_capacity_warning. # The design_capacity_warning is 5% of the energy_full value ENERGY_FULL=$(cat $BATT/energy_full) ALARM_LEVEL=$(expr $ENERGY_FULL \* 5 / 100) else # If nothing is available, we don't want to touch hibernation. # We'll rather report it log "ERR" "You seem to have a broken battery" log "ERR" "Cannot determine design_capacity_warning" log "ERR" "Disabling hibernation" ENOUGH_CHARGE=1 fi if [ "$ALARM_LEVEL" -ne 0 ] ; then if [ "$REMAINING" -le "$ALARM_LEVEL" ] ; then # Restore the state we had before checking this battery, so that # this battery does not count as having enough charge. ENOUGH_CHARGE=$PREV_ENOUGH_CHARGE elif [ "$FOUND_AN_ENABLED_CHECK" -eq 0 ] ; then # This is the only check that is enabled. In that case a non-critical # battery level counts as "enough". (If we would count non-critical # battery levels as enough *always*, then the other settings would # have no effect; this is only a final fallback.) ENOUGH_CHARGE=1 fi fi if [ "$AUTO_HIBERNATION_ON_CRITICAL_BATTERY_LEVEL" -ne 0 ] ; then if [ "$REMAINING" -le "$ALARM_LEVEL" ] ; then ENOUGH_CHARGE_TO_PREVENT_HIBERNATION=$PREV_ENOUGH_CHARGE_TO_PREVENT_HIBERNATION elif [ "$FOUND_AN_ENABLED_HIBERNATION_CHECK" -eq 0 ] ; then ENOUGH_CHARGE_TO_PREVENT_HIBERNATION=1 fi fi # # Fallback: hard values # if [ "$IN_UAH" -ne 0 ] ; then if [ "$MINIMUM_BATTERY_CHARGE_MAH" -ne 0 ] ; then FOUND_AN_ENABLED_CHECK=1 if [ "$REMAINING" -ge $((1000*"$MINIMUM_BATTERY_CHARGE_MAH")) ] ; then ENOUGH_CHARGE=1 fi fi if [ "$AUTO_HIBERNATION_BATTERY_CHARGE_MAH" -ne 0 ] ; then FOUND_AN_ENABLED_HIBERNATION_CHECK=1 if [ "$REMAINING" -ge $((1000*"$AUTO_HIBERNATION_BATTERY_CHARGE_MAH")) ] ; then ENOUGH_CHARGE_TO_PREVENT_HIBERNATION=1 fi fi elif [ "$IN_UWH" -ne 0 ] ; then if [ "$MINIMUM_BATTERY_CHARGE_MWH" -ne 0 ] ; then FOUND_AN_ENABLED_CHECK=1 if [ "$REMAINING" -ge $((1000*"$MINIMUM_BATTERY_CHARGE_MWH")) ] ; then ENOUGH_CHARGE=1 fi fi if [ "$AUTO_HIBERNATION_BATTERY_CHARGE_MWH" -ne 0 ] ; then FOUND_AN_ENABLED_HIBERNATION_CHECK=1 if [ "$REMAINING" -ge $((1000*"$AUTO_HIBERNATION_BATTERY_CHARGE_MWH")) ] ; then ENOUGH_CHARGE_TO_PREVENT_HIBERNATION=1 fi fi else log "ERR" "Failed to determine battery charge. Battery charge units are not in" log "ERR" "mWh, uWh, mAh or uAh." fi else log "VERBOSE" "Battery is not present." fi fi done elif [ "$(echo /proc/acpi/battery/*)" != '/proc/acpi/battery/*' ] ; then log "VERBOSE" "Not on AC and we have batteries in /proc/acpi/battery -- checking minimum battery charge." for BATT in /proc/acpi/battery/* ; do PREV_ENOUGH_CHARGE=$ENOUGH_CHARGE PREV_ENOUGH_CHARGE_TO_PREVENT_HIBERNATION=$ENOUGH_CHARGE_TO_PREVENT_HIBERNATION BATT_STATE=$BATT/state BATT_INFO=$BATT/info log "VERBOSE" "Checking info and state for $BATT." # Only do if the battery is present if ( grep -q 'present:.*yes' $BATT_INFO ) ; then FOUND_AN_ENABLED_CHECK=0 FOUND_AN_ENABLED_HIBERNATION_CHECK=0 # Get the remaining capacity. REMAINING=`grep "remaining capacity:" $BATT_STATE | sed "s/.* \([0-9][0-9]* \).*/\1/" ` if [ -z "$REMAINING" ] ; then log "VERBOSE" "Battery does not report remaining charte. Perhaps it is not present?" REMAINING=0 fi log "VERBOSE" "Remaining charge: $REMAINING" CAPACITY=`grep "design capacity:" $BATT_INFO | sed "s/.* \([0-9][0-9]* \).*/\1/" ` if [ -z "$CAPACITY" ] ; then log "VERBOSE" "Battery does not report capacity. Perhaps it is not present?" CAPACITY=0 fi log "VERBOSE" "Design capacity: $CAPACITY" # Check the charge percentage if [ "$MINIMUM_BATTERY_CHARGE_PERCENT" -ne 0 ] ; then FOUND_AN_ENABLED_CHECK=1 if [ "$CAPACITY" -eq 0 ] ; then log "MSG" "WARNING: Battery does not report a design capacity. Minimum battery" log "MSG" "charge checking does not work without a design capacity." ENOUGH_CHARGE=1 elif [ "$(($REMAINING * 100 / $CAPACITY))" -ge "$MINIMUM_BATTERY_CHARGE_PERCENT" ] ; then ENOUGH_CHARGE=1 fi fi if [ "$AUTO_HIBERNATION_BATTERY_CHARGE_PERCENT" -ne 0 ] ; then FOUND_AN_ENABLED_HIBERNATION_CHECK=1 if [ "$CAPACITY" -eq 0 ] ; then log "MSG" "WARNING: Battery does not report a design capacity. Auto hibernation" log "MSG" "does not work without a design capacity." ENOUGH_CHARGE=1 elif [ "$(($REMAINING * 100 / $CAPACITY))" -ge "$AUTO_HIBERNATION_BATTERY_CHARGE_PERCENT" ] ; then ENOUGH_CHARGE_TO_PREVENT_HIBERNATION=1 fi fi # # Fallback: hard values. # # Determine the reporting unit. IN_MAH=0 IN_MWH=0 if ( grep -q mWh $BATT_INFO ) ; then IN_MWH=1 elif ( grep -q mAh $BATT_INFO ) ; then IN_MAH=1 fi if [ "$IN_MAH" -ne 0 ] ; then if [ "$MINIMUM_BATTERY_CHARGE_MAH" -ne 0 ] ; then FOUND_AN_ENABLED_CHECK=1 if [ "$REMAINING" -ge "$MINIMUM_BATTERY_CHARGE_MAH" ] ; then ENOUGH_CHARGE=1 fi fi if [ "$AUTO_HIBERNATION_BATTERY_CHARGE_MAH" -ne 0 ] ; then FOUND_AN_ENABLED_HIBERNATION_CHECK=1 if [ "$REMAINING" -ge "$AUTO_HIBERNATION_BATTERY_CHARGE_MAH" ] ; then ENOUGH_CHARGE_TO_PREVENT_HIBERNATION=1 fi fi elif [ "$IN_MWH" -ne 0 ] ; then if [ "$MINIMUM_BATTERY_CHARGE_MWH" -ne 0 ] ; then FOUND_AN_ENABLED_CHECK=1 if [ "$REMAINING" -ge "$MINIMUM_BATTERY_CHARGE_MWH" ] ; then ENOUGH_CHARGE=1 fi fi if [ "$AUTO_HIBERNATION_BATTERY_CHARGE_MWH" -ne 0 ] ; then FOUND_AN_ENABLED_HIBERNATION_CHECK=1 if [ "$REMAINING" -ge "$AUTO_HIBERNATION_BATTERY_CHARGE_MWH" ] ; then ENOUGH_CHARGE_TO_PREVENT_HIBERNATION=1 fi fi else log "ERR" "Failed to determine battery charge. Battery charge units are not in" log "ERR" "mWh or mAh." fi CAP_STATE=`sed -r 's/^capacity state:\s*(.*)\s*$/\1/;t;d' "$BATT_STATE"` if [ "$DISABLE_LAPTOP_MODE_ON_CRITICAL_BATTERY_LEVEL" -ne 0 ] ; then if [ "$CAP_STATE" = "critical" ] ; then # Restore the state we had before checking this battery, so that # this battery does not count as having enough charge. ENOUGH_CHARGE=$PREV_ENOUGH_CHARGE elif [ "$FOUND_AN_ENABLED_CHECK" -eq 0 ] ; then # This is the only check that is enabled. In that case a non-critical # battery level counts as "enough". (If we would count non-critical # battery levels as enough *always*, then the other settings would # have no effect; this is only a final fallback.) ENOUGH_CHARGE=1 fi fi if [ "$AUTO_HIBERNATION_ON_CRITICAL_BATTERY_LEVEL" -ne 0 ] ; then if [ "$CAP_STATE" = "critical" ] ; then ENOUGH_CHARGE_TO_PREVENT_HIBERNATION=$PREV_ENOUGH_CHARGE_TO_PREVENT_HIBERNATION elif [ "$FOUND_AN_ENABLED_HIBERNATION_CHECK" -eq 0 ] ; then ENOUGH_CHARGE_TO_PREVENT_HIBERNATION=1 fi fi else log "VERBOSE" "Battery is not present." fi done else ENOUGH_CHARGE=1 ENOUGH_CHARGE_TO_PREVENT_HIBERNATION=1 log "VERBOSE" "Not on AC and could not check battery state -- data loss sensitive features stay enabled and auto-hibernation will not work." fi if [ "$ENABLE_AUTO_HIBERNATION" -ne 0 -a "$ENOUGH_CHARGE_TO_PREVENT_HIBERNATION" -eq 0 ] ; then log "VERBOSE" "None of the batteries have a charge above the auto-hibernation level." log "VERBOSE" "Starting hibernation." if [ -x $HIBERNATE_COMMAND ]; then $HIBERNATE_COMMAND elif [ -f /sys/power/state ]; then grep -q disk /sys/power/state && echo disk > /sys/power/state fi # Don't continue -- if things are configured correctly, then we # will be called on resume. exit 0 fi if [ "$ENOUGH_CHARGE" -eq 0 ] ; then log "VERBOSE" "None of the batteries have a charge above the minimum level." log "VERBOSE" "Deactivating data loss sensitive features." ACTIVATE_WITH_POSSIBLE_DATA_LOSS=0 fi fi if [ "$INIT" -eq 0 ] ; then log "MSG" "Laptop mode " fi # WAS_ACTIVE is used later on. If there is no /var/run/laptop-mode-tools/state, then # we know that laptop mode wasn't active before. WAS_ACTIVE=0 log "VERBOSE" "Checking if desired state is different from current state." if [ -f /var/run/laptop-mode-tools/state ] ; then read WAS_ACTIVE WAS_ON_AC WAS_ACTIVATE_WITH_POSSIBLE_DATA_LOSS WAS_STATE < /var/run/laptop-mode-tools/state if [ "$WAS_STATE" != "" ] ; then if [ "$WAS_ACTIVE" -eq "$ACTIVATE" -a "$WAS_ON_AC" -eq "$ON_AC" -a "$WAS_ACTIVATE_WITH_POSSIBLE_DATA_LOSS" -eq "$ACTIVATE_WITH_POSSIBLE_DATA_LOSS" -a "$WAS_STATE" = "$STATE" -a "$FORCE" -eq 0 ] ; then log "MSG" "$STATE, " if [ "$WAS_ACTIVE" -eq 1 ] ; then log "MSG" "active [unchanged]" if [ "$ACTIVATE_WITH_POSSIBLE_DATA_LOSS" -eq 0 ] ; then log "MSG" " (Data-loss sensitive features disabled.)" fi else log "MSG" "not active [unchanged]" fi exit 0 fi fi else log "VERBOSE" "/var/run/laptop-mode-tools/state does not exist, no previous state." fi echo "$ACTIVATE $ON_AC $ACTIVATE_WITH_POSSIBLE_DATA_LOSS $STATE" > /var/run/laptop-mode-tools/state if [ "$ACTIVATE" -eq 1 ] ; then log "MSG" "$STATE, active" if [ "$ACTIVATE_WITH_POSSIBLE_DATA_LOSS" -eq 0 ] ; then log "MSG" " (Data-loss sensitive features disabled.)" fi else log "MSG" "$STATE, not active" fi # Finally, call laptop-mode-tools modules. The modules can use the settings # from the config files, but they may NOT assume the settings actually exist, # as no defaults have been given for them. # Note that the /usr/local/lib path is deprecated. export FORCE STATE ON_AC ACTIVATE ACTIVATE_WITH_POSSIBLE_DATA_LOSS KLEVEL KMINOR WAS_ACTIVE LM_VERBOSE DEVICES for SCRIPT in /usr/share/laptop-mode-tools/modules/* /usr/local/lib/laptop-mode-tools/modules/* /usr/local/share/laptop-mode-tools/modules/* /etc/laptop-mode/modules/* ; do if [ -z "$MODULES" ] ; then # If a module list has not been provided, execute all modules EXECUTE_SCRIPT=1 else # If a module list has been provided, execute only the listed # modules. EXECUTE_SCRIPT=0 for MODULE in $MODULES; do # Attempt to remove the module name from the end of the # full script path. If the module name matches the # script, the name will be removed from the end of the # full file path, leaving the path to the script. If # there was not a match made, the module name would not # be removed from the path, and $PATH_TO_SCRIPT would # be the same as $SCRIPT. PATH_TO_SCRIPT=${SCRIPT%%$MODULE} # Execute the script if a match was found (module name # was removed from the script path, making it shorter. if [ $PATH_TO_SCRIPT != $SCRIPT ] ; then EXECUTE_SCRIPT=1 fi done fi if [ -x "$SCRIPT" -a $EXECUTE_SCRIPT -eq 1 ] ; then log "VERBOSE" "Invoking module $SCRIPT." SCRIPT_DEBUG=$SCRIPT; # We do this because in start-stop-programs module a $SCRIPT variable is used. That # changes the whole meaning when passed to disableDebug () enableDebug $SCRIPT_DEBUG; (. $SCRIPT) & disableDebug $SCRIPT_DEBUG; else log "VERBOSE" "Module $SCRIPT is not executable or is to be skipped." fi done # Wait for the forks to complete wait exit 0 # This fi closes the if for "readconfig". If I would have indented this one # I would have indented the whole file. :) fi } lmt_load_config # We do a special run of battery polling daemon here so that it does not get # plagued by the lock. We need the polling daemon to be independent of the REQ and INVOC locks. # Polling daemon should *only* have inherited a lock on LMT_BATTPOLL_LOCK. Any other inheritance # for it is a BUG. if [ x$ENABLE_BATTERY_LEVEL_POLLING = x1 ] && [ x$BLACKLIST_IN_FLOCK = x1 ]; then log "VERBOSE" "Battery level polling is enabled." if [ x$ON_AC = x1 ] ; then log "VERBOSE" "On AC, stopping the polling daemon." # In AC mode we disable the polling daemon. killall -q lm-polling-daemon elif [ x$ON_AC = x0 ]; then exec 7>$LMT_BATTPOLL_LOCK; if $FLOCK -n -x -w 1 7; then log "VERBOSE" "Lock acquisition on descriptor 7 succeeded with pid $$"; if ! pidof -x lm-polling-daemon ; then log "VERBOSE" "On battery and there was no polling daemon yet, starting the polling daemon." # If there is no polling daemon, we start one. /usr/share/laptop-mode-tools/module-helpers/lm-polling-daemon < /dev/null > /dev/null 2> /dev/null & fi else log "VERBOSE" "Lock acquisition on descriptor 7 failed with pid $$"; fi # If we are called from the init script with the stop command, lm-polling-daemon # should be killed. if [ x$INITSCRIPT_STOP = x1 ]; then log "VERBOSE" "On Battery, but init script stop is called. Killing lm-polling-daemon" killall -q lm-polling-daemon fi else log "ERR" "Unknown ON_AC state: $ON_AC"; fi else log "VERBOSE" "Battery level polling is disabled." fi lock_retry () { if $FLOCK -n -x -w 1 8; then i=10; while [ $i -ge 1 ] do $FLOCK -x -w 1 9 && lmt_main_function "$@" && break; log "VERBOSE" "Couldn't acquire lock on descriptor 9 in lock_retry(). Retrying.... PID is $$\n" i=$(( $i - 1 )) done else exit 0; fi } # Check and acquire locks and then exec. exec 8>$LMT_REQ_LOCK; if $FLOCK -n -x -w 1 8; then log "VERBOSE" "Prelim lock acquisition on descriptor 8 with pid $$"; else log "VERBOSE" "Couldn't acquire prelim lock on descriptor 8 with pid $$"; fi exec 9>$LMT_INVOC_LOCK; if $FLOCK -n -x -w 1 9; then $FLOCK -u 8; ## Release the invoc lock; log "VERBOSE" "Prelim lock acquisition on descriptor 9 with pid $$"; log "VERBOSE" "Now invoking lmt_main_function with arguments -- $@"; lmt_main_function "$@"; else log "VERBOSE" "Couldn't acquire prelim lock on descriptor 9 with pid $$"; log "VERBOSE" "Now invoking lock_retry with arguments -- $@"; lock_retry "$@"; fi $FLOCK -u 8; $FLOCK -u 9; exit 0;